package com.bwda.dsrs.systemservice.controller;


import com.bwda.dsrs.base.centerbase.BaseConstants;
import com.bwda.dsrs.base.centerbase.response.ResponseEntity;
import com.bwda.dsrs.base.util.AesEncryptPaddingUtil;
import com.bwda.dsrs.base.util.CopyUtil;
import com.bwda.dsrs.base.util.DateUtil;
import com.bwda.dsrs.base.util.UUIDUtil;
import com.bwda.dsrs.systemservice.annotations.IgnoreClientToken;
import com.bwda.dsrs.systemservice.config.https.HttpsClientRequestFactory;
import com.bwda.dsrs.systemservice.domain.Constants;
import com.bwda.dsrs.systemservice.domain.condition.cache.CacheCondition;
import com.bwda.dsrs.systemservice.domain.condition.datadict.DatadictCondition;
import com.bwda.dsrs.systemservice.domain.condition.user.UserCondition;
import com.bwda.dsrs.systemservice.domain.exception.SystemServiceException;
import com.bwda.dsrs.systemservice.domain.form.login.LoginForm;
import com.bwda.dsrs.systemservice.domain.form.login.AhdxLoginForm;
import com.bwda.dsrs.systemservice.domain.form.login.ThirdLoginForm;
import com.bwda.dsrs.systemservice.domain.form.org.OrgCreateForm;
import com.bwda.dsrs.systemservice.domain.po.cache.CachePo;
import com.bwda.dsrs.systemservice.domain.po.datadict.DatadictPo;
import com.bwda.dsrs.systemservice.domain.po.pwdrule.PwdRulePo;
import com.bwda.dsrs.systemservice.domain.po.role.RolePo;
import com.bwda.dsrs.systemservice.domain.po.user.UserPo;
import com.bwda.dsrs.systemservice.domain.po.userinformation.UserInformationPo;
import com.bwda.dsrs.systemservice.domain.po.usersecurity.UserSecurityPo;
import com.bwda.dsrs.systemservice.domain.vo.login.*;
import com.bwda.dsrs.systemservice.eam.controller.GetTokenService;
import com.bwda.dsrs.systemservice.eam_client.model.AccessTokenResponse;
import com.bwda.dsrs.systemservice.eam_client.model.OauthAccessToken;
import com.bwda.dsrs.systemservice.eam_client.model.OauthParams;
import com.bwda.dsrs.systemservice.eam_client.model.OauthRespError;
import com.bwda.dsrs.systemservice.eam_client.util.security.RSAUtils;
import com.bwda.dsrs.systemservice.service.*;
import com.bwda.dsrs.systemservice.util.EncriptUtil;
import com.bwda.dsrs.systemservice.util.util.JwtTokenUtil;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.gson.Gson;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
//import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.bwda.dsrs.systemservice.constants.Constants.*;
import static com.bwda.dsrs.systemservice.domain.Constants.HideFunctions.FUNCTION_HIDE;

/**
 * 登录控制类
 *
 * @author yanyuemei
 * @date 2019/9/10
 */
@RestController
@RequestMapping("/s/login")
public class LoginController extends BaseController {
    @Autowired
    private UserService userService;
    @Autowired
    private UserInformationService userInformationService;
    @Autowired
    private OrgService orgService;
    @Autowired
    private UserSecurityService userSecurityService;
    @Autowired
    private DatadictService datadictService;
    @Autowired
    private CacheService cacheService;

    @Value("${aes_key}")
    private String aeskey;

    @Value("${client_id}")
    private String clientId;
    @Value("${grant_type}")
    private String grantType;
    @Value("${response_type}")
    private String responseType;
    @Value("${get_access_token_url}")
    private String getAccessTokenUrl;
    @Value("${test_get_authorize_code}")
    private String testGetAuthorizeCode;
    @Value("${get_authorize_code_url}")
    private String getAuthorizeCodeUrl;
    @Value("${redirect_url}")
    private String redirectUrl;
    @Value("${test_get_access_token_url}")
    private String testGetAccessTokenUrl;
    @Value("${private_key}")
    private String privateKey;

//    @Autowired
//    private RedisTemplate redisTemplate;
    @Autowired
    private RoleService roleService;
    @Autowired
    private LoginRuleService loginRuleService;

    @Value("${user_token_expires}")
    private long expireTime;


    @Autowired
    DefaultKaptcha producer;

    private final static String CODE = "code";
    private final static int INT2 = 2;
    private final static int INT3 = 3;
    private final static int INT4 = 4;


    @ApiOperation(value = "登录", notes = "登录", httpMethod = "GET")
    @RequestMapping(value = "/userLogin", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreClientToken
    public ResponseEntity<LoginVo> userLogin(@ModelAttribute @Valid LoginForm form) throws SystemServiceException, Exception {
        //根据usercode查看用户安全策略
        String userCode = form.getUsername();
        UserPo userPo = userService.queryUserByUserCode(userCode);
        LoginVo loginVo = new LoginVo();
        //获取用户详细信息
        if (userPo == null || StringUtils.isEmpty(userPo.getUserCode())) {
            return this.getFailResult("用户名或密码不正确");
        }
        if (USER_FREEZE == userPo.getUserState()) {
            return this.getFailResult("用户已冻结，请联系管理员");
        } else if (USER_LOCK == userPo.getUserState()) {
            return this.getFailResult("用户已锁定，请联系管理员");
        } else if (USER_LEAVE == userPo.getUserState()) {
            return this.getFailResult("用户已离职");
        } else if (USER_LOG_OFF == userPo.getUserState()) {
            return this.getFailResult("用户已注销");
        } else {
            //根据usercode查看用户安全策略
            //用户安全策略不存在，则生成用户策略
            UserSecurityPo userSecurityPo = userSecurityService.querySecurityByUserCode(userCode);

            if (userSecurityPo != null) {
                //获取登录策略
                PwdRulePo pwdRulePo = loginRuleService.queryWithValid(ONE_INT);
                //一直启用验证码
                if (ONE_INT.equals(pwdRulePo.getEnableVerifiCode())) {
                    if (StringUtils.isEmpty(form.getVerifyCode())) {
                        return this.getFailResult(BaseConstants.RESCODE_VERIFY_CODE_LOGIN, "需要验证码登录");
                    } else {
                        boolean codeflag = validateVeifyCode(form.getVerifyCodeUuid(), form.getVerifyCode());
                        if (!codeflag) {
                            return this.getFailResult(BaseConstants.RESCODE_VERIFY_CODE_LOGIN, "验证码有误");
                        }
                    }
                }else if (TWO_INT.equals(pwdRulePo.getEnableVerifiCode())) {
                    //登录失败验证码认证次数限制
                    int loginFailTime = userSecurityPo.getLoginFailCount() == null ? 0 : userSecurityPo.getLoginFailCount();
                    //错误次数
                    if (loginFailTime >= pwdRulePo.getVerifiFailTime() || StringUtils.isNotEmpty(form.getVerifyCodeUuid())) {
                        String rMsg = checkUser(form);
                        if(rMsg != null){
                            return this.getFailResult(BaseConstants.RESCODE_VERIFY_CODE_LOGIN, checkUser(form));
                        }
                    }
                }
            }
            if (userSecurityPo == null) {
                return getFailResult("用户名或者密码不正确");
            }
            //校验用户名密码
            Map<String, String> result = this.getToken(form, userPo, userSecurityPo);
            if (StringUtils.equals(ONE_STR, result.get(CODE))) {
                return this.getFailResult(result.get("msg"));
            } else if (StringUtils.equals(TWO_STR, result.get(CODE))) {
                return this.getFailResult(BaseConstants.RESCODE_VERIFY_CODE_LOGIN, "需要验证码登录");
            } else {
                loginVo.setToken(result.get("msg"));
                //根据用户名获取角色
                List<RolePo> roles = roleService.queryUserRoleList(userCode);
                if (roles == null || roles.isEmpty()) {
                    throw new SystemServiceException("用户未关联角色，请联系管理员！");
                }
                loginVo.setRoles(roles);
            }
            //密码是否过期

        }
        return getSuccessResult("登录成功", loginVo);
    }

    @ApiOperation(value = "系统跳转登录", notes = "系统跳转登录（接口）", httpMethod = "GET")
    @RequestMapping(value = "/ahydTempLogin", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreClientToken
    public ResponseEntity<LoginVo> thirdLogin(@ModelAttribute @Valid ThirdLoginForm form) throws SystemServiceException, Exception {

        form.setUserCode("wang");
        form.setCallBackToken("-----");
        //根据usercode查看用户安全策略
        if (StringUtils.isEmpty(form.getUserCode()) || StringUtils.isEmpty(form.getCallBackToken())) {
            return this.getFailResult("认证失败，未获取到认证信息");
        }



        String userCode = form.getUserCode();
        UserPo userPo = userService.queryUserByUserCode(form.getUserCode());
        LoginVo loginVo = new LoginVo();
        //获取用户详细信息
        if (userPo == null || StringUtils.isEmpty(userPo.getUserCode())) {
            return this.getFailResult("用户名或密码不正确");
        }
        if (USER_FREEZE == userPo.getUserState()) {
            return this.getFailResult("用户已冻结，请联系管理员");
        } else if (USER_LOCK == userPo.getUserState()) {
            return this.getFailResult("用户已锁定，请联系管理员");
        } else if (USER_LEAVE == userPo.getUserState()) {
            return this.getFailResult("用户已离职");
        } else if (USER_LOG_OFF == userPo.getUserState()) {
            return this.getFailResult("用户已注销");
        } else {
            //根据usercode查看用户安全策略
            //用户安全策略不存在，则生成用户策略
            UserSecurityPo userSecurityPo = userSecurityService.querySecurityByUserCode(userCode);


            if (userSecurityPo == null) {
                return getFailResult("用户名或者密码不正确");
            }
            //校验用户名密码
            String token = getToken(userPo);
            loginVo.setToken(token);
            //根据用户名获取角色
            List<RolePo> roles = roleService.queryUserRoleList(userCode);
            if (roles == null || roles.isEmpty()) {
                throw new SystemServiceException("用户未关联角色，请联系管理员！");
            }
            loginVo.setRoles(roles);
        }
        return getSuccessResult("登录成功", loginVo);
    }

    @ApiOperation(value = "统一登录获取系统信息和接口地址", notes = "统一登录获取系统信息和接口地址", httpMethod = "GET")
    @RequestMapping(value = "/ahdxLogin", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreClientToken
    public ResponseEntity<AhdxLoginVo> ahdxLogin(@ModelAttribute @Valid AhdxLoginForm form){
//        check accesstoken
//        if(StringUtils.isBlank(form.getAccessToken())){
//            return this.getFailResult("请先进行统一认证");
//        }
//        String json = RSAUtils.decryptByPrivateKeyStr(form.getAccessToken(),PRIVATE_KEY);
//        Gson gson = new Gson();
//        AccessTokenResponse accessTokenResponse = gson.fromJson(json,AccessTokenResponse.class);
//        //根据usercode查看用户安全策略
//        String userCode = accessTokenResponse.getUser().getStaffAccount();
//        UserPo userPo = userService.queryUserByUserCode(userCode);
//        LoginVo loginVo = new LoginVo();
//        Map<String, String> result = this.getToken(accessTokenResponse, userPo);
//        loginVo.setToken(result.get("msg"));
//        //根据用户名获取角色
//        List<RolePo> roles = roleService.queryUserRoleList(userCode);
//        if (CollectionUtils.isEmpty(roles)) {
//            throw new SystemServiceException("用户未关联角色，请联系管理员！");
//        }
//        loginVo.setRoles(roles);
        AhdxLoginVo ahdxLoginVo = new AhdxLoginVo();
        ahdxLoginVo.setClienId(clientId);
        ahdxLoginVo.setResponseType(responseType);
//        ahdxLoginVo.setGetAuthorizeCodeUrl(GET_AUTHORIZE_CODE_URL);
        ahdxLoginVo.setGetAuthorizeCodeUrl(testGetAuthorizeCode);
        return getSuccessResult(ahdxLoginVo);
    }

    @ApiOperation(value = "通过code统一登录", notes = "通过code统一登录", httpMethod = "GET")
    @RequestMapping(value = "/ahdxLoginByCode", method = {RequestMethod.GET, RequestMethod.POST})
    @IgnoreClientToken
    public ResponseEntity<LoginVo> ahdxLoginByCode(@ModelAttribute @Valid AhdxLoginForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
//        check accesstoken
        if(StringUtils.isBlank(form.getCode())){
            return this.getFailResult("请先获取授权码");
        }
        if(StringUtils.isBlank(form.getClientId())){
            return this.getFailResult("请先获取应用标识");
        }
        if(!form.getClientId().equals(clientId)){
            return this.getFailResult("应用标识无效");
        }
//        CreateGetCodeRedirectUrl codeUrl = new CreateGetCodeRedirectUrl();
//        String url = codeUrl.createUrl(TEST_GET_AUTHORIZE_CODE, CLIEND_ID,RANGT_TYPE, REDIRECT_URL);
        request.setAttribute("code",form.getCode());
        request.setAttribute("client_id",form.getClientId());
        request.setAttribute("grant_type", grantType);
//        request.setAttribute("redirect_url",GET_ACCESS_TOKEN_URL);
        request.setAttribute("redirect_url", testGetAccessTokenUrl);
        AccessTokenResponse accessTokenResponse = getAccessToken(request,response);
        //根据usercode查看用户安全策略
        String userCode = accessTokenResponse.getUser().getStaffAccount();
        UserPo userPo = userService.queryUserByUserCode(userCode);
        LoginVo loginVo = new LoginVo();
        Map<String, String> result = this.getToken(accessTokenResponse, userPo);
        loginVo.setToken(result.get("msg"));
        //根据用户名获取角色
        List<RolePo> roles = roleService.queryUserRoleList(userCode);
        if (CollectionUtils.isEmpty(roles)) {
            return getFailResult("用户未关联角色，请联系管理员！");
        }
        loginVo.setRoles(roles);
        return getSuccessResult("登录成功", loginVo);
    }


    private AccessTokenResponse getAccessToken(HttpServletRequest request, HttpServletResponse response) throws  IOException {
        AccessTokenResponse accessTokenVo = new AccessTokenResponse();
        response.setContentType("text/html;charset=UTF-8");
//        PrintWriter out = response.getWriter();
        OauthParams oauthParams = new OauthParams();
        GetTokenService getToken = new GetTokenService();
        // 获取由统一认证平台颁发的code
//        String code = request.getParameter("code");
        String code = request.getAttribute("code").toString();
        if (code != null) {
            oauthParams.setClientId(clientId);// client_id由统一认证平台颁发
            oauthParams.setCode(code);
            oauthParams.setGrantType(grantType);// grant_type固定值为authorization_code
//            oauthParams.setAuthUrl(GET_ACCESS_TOKEN_URL);
            oauthParams.setAuthUrl(testGetAccessTokenUrl);
            oauthParams.setRedirectUri(redirectUrl);
            Map<String, Object> map = new HashMap<String, Object>(16);
            // 调用eam-client，获取access_token
            map = getToken.getToken(oauthParams);
            String statusCode = (String) map.get("statusCode");
            if ("200".equals(statusCode)) {
                OauthAccessToken accessToken = new OauthAccessToken();
                accessToken = (OauthAccessToken)map.get("accessToken");
                if(accessToken != null && !"".equals(accessToken)){
                    String json = null;
                    Gson gson = new Gson();
                    try {
//                        out.println(accessToken.getAccessToken());
                        json = RSAUtils.decryptByPrivateKeyStr(accessToken.getAccessToken(), privateKey);
                        request.getSession().setAttribute("accessToken", json);
//                        out.print(json);
                        System.out.println(json);
                        accessTokenVo = gson.fromJson(json,AccessTokenResponse.class);
//                        request.getSession().setAttribute("orgId", accessTokenVo.getUser().getOrgUuid());
//                        request.setAttribute("userName", accessTokenVo.getUser().getStaffAccount());
//                        request.getRequestDispatcher("http://192.168.201.55:8002/s/login/userLogin").forward(request, response);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
//                        out.print("error");
                    }

                }
            } else {
                OauthRespError error = new OauthRespError();
                error = (OauthRespError) map.get("error");
                if(error != null && !"".equals(error)){
//                    out.print(error.getError());
//                    out.print("<br/>" + error.getErrorDescription());
                }else{
//                    out.print("return is null");
                }
            }
        } else {
//            out.print("code is null");

        }

        return accessTokenVo;
    }

    private String checkUser(LoginForm form) throws SystemServiceException{
        if (StringUtils.isEmpty(form.getVerifyCode())) {
            return "需要验证码登录";
        }else if (StringUtils.isNotEmpty(form.getVerifyCodeUuid())) {
            //如果开启验证码认证并且验证码为空，则提醒输入验证码
            boolean codeFlag = validateVeifyCode(form.getVerifyCodeUuid(), form.getVerifyCode());
            if (!codeFlag) {
                return "验证码有误";
            }
        }

        return null;
    }


    @ApiOperation(value = "退出登录", notes = "退出登录", httpMethod = "GET")
    @RequestMapping(value = "/removeToken", method = {RequestMethod.GET, RequestMethod.POST})
    public ResponseEntity<String> removeToken() throws SystemServiceException {
//        String token = getAuthorization();
//        if (redisTemplate.hasKey(token)) {
//            redisTemplate.delete(token);
//        }
//        return getSuccessResult("退出登录成功");
        String token = getAuthorization();
        CacheCondition cacheCondition = new CacheCondition();
        cacheCondition.setCacheKey(token);
        cacheCondition.setPageSize(Integer.MAX_VALUE);
        List<CachePo> cachePos = cacheService.queryList(cacheCondition);
        if (!CollectionUtils.isEmpty(cachePos)) {
            cacheService.delete(cachePos.get(0).getId());
        }
        return getSuccessResult("退出登录成功");
    }

    @IgnoreClientToken
    @ApiOperation(value = "获取验证码", notes = "获取验证码", httpMethod = "POST")
    @RequestMapping(value = "/getVerifyCode", method = {RequestMethod.GET, RequestMethod.POST})
    public ResponseEntity<VerifyCodeRandomVo> getVerifyCode(@ModelAttribute @Valid LoginForm form) throws SystemServiceException, Exception {
        //生成验证码
        String text = producer.createText();
        String uuid = UUIDUtil.getUuid();
//        redisTemplate.opsForValue().set("code_" + uuid, text, 60, TimeUnit.SECONDS);
        CachePo cachePo = new CachePo();
        cachePo.setCacheKey("code_" + uuid);
        cachePo.setToken(text);
        cacheService.insert(cachePo);
        BufferedImage bi = producer.createImage(text);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bi, "jpeg", outputStream);
        String base64Image = "data:image/jpeg;base64," + Base64.encodeBase64String(outputStream.toByteArray());
        VerifyCodeRandomVo verifyCodeVo = new VerifyCodeRandomVo();
        verifyCodeVo.setImageBase64(base64Image);
        verifyCodeVo.setVerifyCodeUuid(uuid);
        return getSuccessResult("", verifyCodeVo);
    }


    /**
     * 获取是否需要验证码
     *
     * @return
     */
    @PostMapping("/dict/generateVcode")
    @IgnoreClientToken
    public ResponseEntity generateVcode(HttpServletRequest request) throws SystemServiceException {
        String value = datadictService.getDataDictValByCode("verifyCodeSwitch");
        return getSuccessResult("操作成功", value);
    }

    /**
     * 认证模式 0：内部认证，1：外部认证
     *
     * @return
     */
    @PostMapping("/dict/authSwitch")

    public ResponseEntity authSwitch() throws SystemServiceException {
        String value = datadictService.getDataDictValByCode("authSwitch");
        return getSuccessResult("", value);
    }


    private boolean validateVeifyCode(String verifyCodeUuid, String code) throws SystemServiceException {
//        String key = "code_" + verifyCodeUuid;
//        if (!redisTemplate.hasKey(key)) {
//            throw new SystemServiceException("验证码不正确");
//        }
//
//        Object codeObj = redisTemplate.opsForValue().get(key);
//
//        if (codeObj == null) {
//            throw new SystemServiceException("验证码不正确");
//        }
//
//        String saveCode = codeObj.toString();
//        if (StringUtils.isBlank(saveCode)) {
//            redisTemplate.delete(key);
//            throw new SystemServiceException("验证码不正确");
//        }
//
//        if (!StringUtils.equals(saveCode, code)) {
//            redisTemplate.delete(key);
//            throw new SystemServiceException("验证码不正确");
//        }
//        redisTemplate.delete(key);
//        return true;

        //去redis
        String key = "code_" + verifyCodeUuid;
        CacheCondition cacheCondition = new CacheCondition();
        cacheCondition.setCacheKey(key);
        cacheCondition.setPageSize(Integer.MAX_VALUE);
        List<CachePo> cachePos = cacheService.queryList(cacheCondition);
        if (CollectionUtils.isEmpty(cachePos)) {
            throw new SystemServiceException("验证码不正确");
        }

        Object codeObj = cachePos.get(0).getToken();

        if (codeObj == null) {
            throw new SystemServiceException("验证码不正确");
        }

        String saveCode = codeObj.toString();
        if (StringUtils.isBlank(saveCode)) {
            cacheService.delete(cachePos.get(0).getId());
            throw new SystemServiceException("验证码不正确");
        }

        if (!StringUtils.equals(saveCode, code)) {
            cacheService.delete(cachePos.get(0).getId());
            throw new SystemServiceException("验证码不正确");
        }
        cacheService.delete(cachePos.get(0).getId());
        return true;
    }


    /**
     * 获取用户token
     *
     * @param user
     * @return
     */

    private String getToken(UserPo user) {
        //获取组织信息，组织管理员
        OrgCreateForm org = orgService.queryByIdOrg(user.getOrgId());
        String orgName = "";
        String orgCode = "";
        if (org != null) {
            orgName = org.getOrgName();
            orgCode = org.getOrgAdminCode();
        }
        String token = JwtTokenUtil.sign(user.getUserCode(), user.getUserName(), String.valueOf(user.getOrgId()), orgName, orgCode, "dsrs");
        //TODO  以前是根据userCode 存放，现改为<token，token>,因为一个人可能会同时登陆多个，后面还会更加的细分，token里也只能保存一个userCode其他信息也不应该存放
//        redisTemplate.opsForValue().set(token, token);
//        redisTemplate.expire(token, expireTime, TimeUnit.SECONDS);
        CachePo cachePo = new CachePo();
        cachePo.setCacheKey(token);
        cachePo.setToken(token);
        cacheService.insert(cachePo);
        return token;
    }

    private Map<String, String> getToken(LoginForm form, UserPo user, UserSecurityPo userSecurityPo) throws SystemServiceException {
        Map<String, String> result = new HashMap<String, String>(16);
        String userCode = user.getUserCode();
        //用户输入的密码
        String password = form.getPassword();
        try {
            password = AesEncryptPaddingUtil.decrypt(password, aeskey);

        } catch (Exception e) {
            logger.error("====密码解密异常：" + e.getMessage());
            throw new SystemServiceException();
        }
        int loginFailTime = userSecurityPo.getLoginFailCount() == null ? 0 : userSecurityPo.getLoginFailCount();
        //获取登录策略
        PwdRulePo pwdRulePo = loginRuleService.queryWithValid(ONE_INT);
        if (loginFailTime > pwdRulePo.getFailTimes()) {
            if (user.getUserState() == NOT_DELETED) {
                userService.updateState(String.valueOf(user.getUserId()), 3L);

            }
            result.put(CODE, ONE_STR);
            result.put("msg", "用户已锁定，请联系管理员");
            return result;
        } else {
            boolean authPwdState = false;
            //是否开启用户同步密码认证
            String outerPwdAuth = datadictService.getDataDictValByCode("root.outer.authway");
            logger.info("密码认证方式为 root.outer.authway{}", outerPwdAuth);
            //服务默认加密方式（未开启用户同步密码认证或者通过内部创建的用户）
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            //验证用户输入密码与数据库密码是否一致
//            logger.info(password);
            authPwdState = encoder.matches(password, user.getPassword());
            //（简单判断，后面的人可以再补充）再以MD5加密方式判断密码，若一致则认为是老4A的账号
            if (null != user.getPassword() && user.getPassword().equals(EncriptUtil.encodePwd(password))) {
                authPwdState = true;
            }
            // 这种常量毫无意义
            if (Constants.FOUR_INT.equals(user.getUserSource())) {
                if (Constants.ZERO_STR.equals(outerPwdAuth) || Constants.ONE_INT.equals(user.getUserSource())) {
                    //MD5加密;
                    password = EncriptUtil.encodePwd(password);
                    if (password.equals(user.getPassword())) {
                        authPwdState = true;
                    } else {
                        authPwdState = false;
                    }
                } else {
                    //4a用户登录密码md5加密方式 0：密码直接md5,1：用户名+密码+密码随机数md5
                    String loginMd5 = datadictService.getDataDictValByCode("root.loginMd5");
                    String fullPwdMd5 = "";
                    String fullPwd = "";
                    if (Constants.ZERO_STR.equals(loginMd5)) {
                        fullPwd = password;
                    } else {
                        fullPwd = userCode + password + user.getSalt();
                    }
                    fullPwdMd5 = EncriptUtil.encodePwd(fullPwd);
                    if (user.getPassword().equals(fullPwdMd5) || user.getPassword().equals(password)) {
                        authPwdState = true;
                    } else {
                        authPwdState = false;
                    }
                }
            }
//            authPwdState = true;
            if (authPwdState) {
                //用户名密码校验正确，则更新安全策略登录成功次数并失败次数置0
                userSecurityPo.setLoginFailCount(ZERO);
                userSecurityService.update(userSecurityPo);

                //获取token
                String token = getToken(user);

                result.put("code", ZERO_STR);
                result.put("msg", token);
                return result;
            } else {
                //普通用户
                Boolean isUserFlag = true;
                //如果是三员其中一员，则无需锁定用户
                if (IS_ADMIN.equals(userCode) || IS_AUDITADMIN.equals(userCode) || IS_SECADMIN.equals(userCode)) {
                    isUserFlag = false;
                }
                if (isUserFlag) {
                    //用户名密码校验不正确，则更新安全策略登录失败次数
                    userSecurityPo.setLoginFailCount((userSecurityPo.getLoginFailCount() == null ? 0 : userSecurityPo.getLoginFailCount()) + 1);

                    if ((loginFailTime + 1) >= pwdRulePo.getFailTimes()) {
                        userService.updateState(user.getUserId().toString(), USER_LOCK_L);
                        //记录锁定时间
                        userService.updateLockDate(user.getUserCode());

                    }
                    userSecurityService.update(userSecurityPo);
                }
                result.put("code", ONE_STR);
                result.put("msg", "用户名或密码不正确");
                return result;
            }
        }

    }
    private Map<String, String> getToken(AccessTokenResponse accessTokenResponse, UserPo user) {
        Map<String, String> result = new HashMap<String, String>(16);
        //用户输入的密码
//        String password = accessTokenResponse.getTokenvalue();
        //获取token
        String token = getToken(user);
        result.put("code", ZERO_STR);
        result.put("msg", token);
        return result;
    }

    /**
     * 获取用户权限
     *
     * @param request
     * @return
     */
    @PostMapping("/getUserDetail")
    public ResponseEntity getUserDetail(HttpServletRequest request) throws SystemServiceException {
        String authentication = request.getHeader(TOKEN_HEADER);
        Map<String, Object> dbAuthsMap = new HashMap<String, Object>(16);
        String userCode = JwtTokenUtil.getUserCode(authentication);
        //获取用户详细信息
        UserPo userPo = userService.queryUserByUserCode(userCode);
        if (userPo != null && userPo.getUserSource() == 1) {
            UserInformationPo userInformationPo = userInformationService.query(userPo.getUserCode());
            if (userInformationPo != null) {
                userPo.setSex(userInformationPo.getSex());
            }
            // 第一次登录需要修改密码,密码已经过期同样需要修改密码,
            UserSecurityPo userSecurityPo = userSecurityService.querySecurityByUserCode(userCode);
            //获取密码有效期
            //获取登录策略
            PwdRulePo pwdRulePo = loginRuleService.queryWithValid(com.bwda.dsrs.systemservice.domain.Constants.ONE_INT);
            Integer notifyDays = pwdRulePo.getNotifyDays();
            //获取上次修改密码时间
            Date updatePwdTime = userSecurityPo.getPwdUpdateTime();
            if (notifyDays == null || updatePwdTime == null) {
                userPo.setPwdEditWarning(com.bwda.dsrs.systemservice.domain.Constants.UpdateType.NO_UPDATE);
            } else {
                //校验是否在到期提醒天数
                Integer diffDay = DateUtil.daysBetween(new Date(), userSecurityPo.getPwdUpdateTime());
                if (diffDay < pwdRulePo.getNotifyDays()) {
                    userPo.setPwdEditWarning(com.bwda.dsrs.systemservice.domain.Constants.UpdateType.UPDATE);
                    userPo.setPwdWarningDays(diffDay);
                } else {
                    userPo.setPwdEditWarning(com.bwda.dsrs.systemservice.domain.Constants.UpdateType.NO_UPDATE);
                }

                if (diffDay < 0) {
                    userPo.setPwdEdit(com.bwda.dsrs.systemservice.domain.Constants.UpdateType.UPDATE);
                }
            }
            userPo.setPassword(null);
            //获取上次修改密码时间
            Date lastUpdatePwdTime = userSecurityPo.getPwdLastUpdateTime();
            Integer validDays = pwdRulePo.getValidDays();
            if (lastUpdatePwdTime == null || validDays == null) {
                userPo.setPwdEdit(com.bwda.dsrs.systemservice.domain.Constants.UpdateType.UPDATE);
            } else {
                Date exprieDate = DateUtil.addDateDay(lastUpdatePwdTime, validDays);
                if (new Date().after(exprieDate)) {
                    userPo.setPwdEdit(com.bwda.dsrs.systemservice.domain.Constants.UpdateType.UPDATE);
                }
            }
            dbAuthsMap.put("userinfo", userPo);
        } else {
            dbAuthsMap.put("userinfo", userPo);
        }
        List<RolePo> roleList = roleService.queryUserRoleList(userCode);
        if (roleList != null && roleList.size() > 0) {
            dbAuthsMap.put("roles", roleList);
        }
        OrgCreateForm orgForm = orgService.queryOrg(userCode);
        if (orgForm != null) {
            dbAuthsMap.put("org", orgForm);
        }
        dbAuthsMap.put("configs", getConfigs());
        return getSuccessResult(dbAuthsMap);
    }

    /**
     * 系统的配置
     *
     * @return
     */
    private ConfigVo getConfigs() {
        ConfigVo configVo = new ConfigVo();

        DatadictCondition condition = new DatadictCondition();
        condition.setDelFlag(NOT_DELETED);
        condition.setDataDictTypeCode(FUNCTION_HIDE);
        condition.setStatus(ZERO);
        List<DatadictPo> datadictPoList = datadictService.queryList(condition);
        datadictPoList.forEach(item -> {
            if (item.getDataDictCode().equals(Constants.HideFunctions.HIDE_DOWNLOAD) && Constants.HideFunctions.VALUE_HIDE.equals(item.getDataDictValue())) {
                configVo.setHideDownload(true);
            } else if (item.getDataDictCode().equals(Constants.HideFunctions.HIDE_EDIT) && Constants.HideFunctions.VALUE_HIDE.equals(item.getDataDictValue())) {
                configVo.setHideEdit(true);
            } else if (item.getDataDictCode().equals(Constants.HideFunctions.HIDE_PREVIEW) && Constants.HideFunctions.VALUE_HIDE.equals(item.getDataDictValue())) {
                configVo.setHidePreview(true);
            } else if (item.getDataDictCode().equals(Constants.HideFunctions.HIDE_DOWNLOAD_CLIENT) && Constants.HideFunctions.VALUE_HIDE.equals(item.getDataDictValue())) {
                configVo.setHideDownloadClient(true);
            } else if (item.getDataDictCode().equals(Constants.HideFunctions.HIDE_SHARE) && Constants.HideFunctions.VALUE_HIDE.equals(item.getDataDictValue())) {
                configVo.setHideShare(true);
            } else if (item.getDataDictCode().equals(Constants.HideFunctions.HIDE_FLOW) && Constants.HideFunctions.VALUE_HIDE.equals(item.getDataDictValue())) {
                configVo.setHideFlow(true);
            }
        });


        return configVo;
    }


    /**
     * MenuQueryForm转换为MenuCondition
     *
     * @param form
     * @return
     */
    private UserCondition getConditionByQueryForm(LoginForm form) {
        UserCondition condition = CopyUtil.transfer(form, UserCondition.class);
        return condition;
    }

}
